package com.app.response;

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * * <p>
 * * REST API 返回结果
 * * </p>
 *
 * @author ZhengJunJie
 * @date 2020/5/19
 */
@Data
@Accessors(chain = true)
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BaseResponse<T extends Serializable> implements Serializable {

    @ApiModelProperty("响应码")
    private String code;

    @ApiModelProperty("是否成功")
    private Boolean success;

    @ApiModelProperty("响应消息")
    private String message;

    @ApiModelProperty("响应数据")
    private T data;

    @ApiModelProperty("响应时间")
    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime time;

    public static BaseResponse<Boolean> result(ResponseCode responseCode) {
        return result(responseCode, null);
    }

    public static <T extends Serializable> BaseResponse<T> result(ResponseCode responseCode, T data) {
        return result(responseCode, null, data);
    }

    public static <T extends Serializable> BaseResponse<T> result(ResponseCode responseCode, String message, T data) {
        boolean success = false;
        if (responseCode.getCode().equalsIgnoreCase(ResponseCode.SUCCESS.getCode())) {
            success = true;
        }
        String apiMessage = responseCode.getMsg();
        if (StringUtils.isBlank(message)) {
            message = apiMessage;
        }
        @SuppressWarnings("unchecked")
        BaseResponse<T> response = (BaseResponse<T>) BaseResponse.builder()
                .code(responseCode.getCode())
                .message(message)
                .data(data)
                .success(success)
                .time(LocalDateTime.now())
                .build();
        return response;
    }

    public static BaseResponse<Boolean> success() {
        return success(null);
    }

    public static <T extends Serializable> BaseResponse<T> success(T data) {
        return result(ResponseCode.SUCCESS, data);
    }

    public static <T extends Serializable> BaseResponse<T> success(String message, T data) {
        return result(ResponseCode.SUCCESS, message, data);
    }

    public static BaseResponse<Boolean> fail() {
        return fail(ResponseCode.SYSTEM_ERROR);
    }

    public static BaseResponse<Boolean> fail(ResponseCode responseCode) {
        return result(responseCode, null);
    }

    public static BaseResponse<String> fail(String message) {
        return result(ResponseCode.SYSTEM_ERROR, message, null);
    }

    public static <T extends Serializable> BaseResponse<T> fail(ResponseCode responseCode, String message) {
        return result(responseCode, message, null);
    }

    public static <T extends Serializable> BaseResponse<T> fail(String code, String message) {
        return result(ResponseCode.getByCode(code), message, null);
    }
}